package vip.xiaonuo.biz.modular.detect.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.barn.modular.barn.mapper.BizBarnMapper;
import vip.xiaonuo.biz.modular.detect.entity.*;
import vip.xiaonuo.biz.modular.detect.mapper.MixMapper;
import vip.xiaonuo.biz.modular.detect.service.BizDetectService;
import vip.xiaonuo.biz.modular.detect.service.utils.DetectImageUtil;
import vip.xiaonuo.biz.modular.detect.service.utils.SendEmailUtil;
import vip.xiaonuo.biz.modular.detectrecord.param.BizDetectRecordAddParam;
import vip.xiaonuo.biz.modular.detectrecord.service.BizDetectRecordService;
import vip.xiaonuo.column.modular.column.entity.BizColumn;
import vip.xiaonuo.column.modular.column.mapper.BizColumnMapper;
import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.dev.modular.file.entity.DevFile;
import vip.xiaonuo.dev.modular.file.mapper.DevFileMapper;
import vip.xiaonuo.henhouse.modular.henhouse.entity.BizHenhouse;
import vip.xiaonuo.henhouse.modular.henhouse.mapper.BizHenhouseMapper;

import javax.annotation.Resource;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;

/**
 * @author
 * @date 2023/10/28、17:11
 */
@Service
@Slf4j
public class BizDetectServiceImpl extends ServiceImpl<DevFileMapper, DevFile> implements BizDetectService {
    private final String ABNORMAL = "异常";

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private DetectImageUtil detectImageUtil;

    @Resource
    private BizHenhouseMapper bizHenhouseMapper;

    @Resource
    private BizBarnMapper bizBarnMapper;

    @Resource
    private BizColumnMapper bizColumnMapper;

    @Autowired
    private MixMapper mixMapper;

    @Resource
    private BizDetectRecordService detectRecordService;

    // 存储异步结果的ConcurrentHashMap
    private final ConcurrentHashMap<String, CompletableFuture<BizDetectResult>> futures = new ConcurrentHashMap<>();

    private final ExecutorService taskExecutor;

    @Autowired
    public BizDetectServiceImpl(ExecutorService taskExecutor) {
        this.taskExecutor = taskExecutor;
    }


    /**
     * 检测过程
     * 通过监听消息队列来判断检测结果
     *
     * @param bizDetectImageParam 检测表单
     * @return {@link CommonResult}<{@link BizDetectResult}>
     */
    @Override
    public CommonResult detect(BizDetectImageParam bizDetectImageParam) {
        // 根据id查找出文件路径
        String imgId = bizDetectImageParam.getImageId();
        log.info("检测图片：{}",imgId);
        String path = detectImageUtil.getImagePath(imgId);
        PythonDetectParam pythonDetectParam = new PythonDetectParam();
        pythonDetectParam.setPath(path);
        pythonDetectParam.setHenhouseId(bizDetectImageParam.getHenhouseId());
        pythonDetectParam.setColumnId(bizDetectImageParam.getColumnId());
        pythonDetectParam.setBarnId(bizDetectImageParam.getBarnId());
        pythonDetectParam.setRequestId(bizDetectImageParam.getRequestId());
        taskExecutor.submit(() -> rabbitTemplate.convertAndSend("jyl.detect","path",pythonDetectParam));
        return CommonResult.ok();
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "detect.info" , durable = "true"),
            exchange = @Exchange(name = "jyl.detect"),
            key = "info"
    ))
    public void handleResultMessage(PythonDetectResult pythonDetectResult){
        log.info("处理检测结果消息：{}",pythonDetectResult.getResult());
        if (pythonDetectResult.getResult().equals("异常")){
            BizDetectFormParam bizDetectFormParam = new BizDetectFormParam(
                    pythonDetectResult.getHenhouseId(),
                    pythonDetectResult.getBarnId(),
                    pythonDetectResult.getColumnId(),
                    pythonDetectResult.getResult()
            );
            updateState(bizDetectFormParam);
        }

        BizDetectRecordAddParam bizDetectRecordAddParam = new BizDetectRecordAddParam();
        BeanUtil.copyProperties(pythonDetectResult,bizDetectRecordAddParam);
        detectRecordService.add(bizDetectRecordAddParam);
    }

    @Override
    public CommonResult updateState(BizDetectFormParam bizDetectFormParam) {
        Integer henhouseId = bizDetectFormParam.getHenhouseId();
        String barnId = bizDetectFormParam.getBarnId();
        String columnId = bizDetectFormParam.getColumnId();

        // 执行批量更新
        int rows = mixMapper.batchUpdateState(henhouseId, barnId, columnId, ABNORMAL);

        return rows > 0 ? CommonResult.ok() : CommonResult.error("更新失败");
    }

    @Override
    public CommonResult sendWarningEmail(BizDetectFormParam bizDetectFormParam) {
        Integer henhouseId = bizDetectFormParam.getHenhouseId();
        String columnId = bizDetectFormParam.getColumnId();

        QueryWrapper<BizHenhouse> henhouseQueryWrapper = new QueryWrapper<>();
        QueryWrapper<BizColumn> columnQueryWrapper = new QueryWrapper<>();

        if (henhouseId != null && henhouseId != -1) {
            henhouseQueryWrapper.lambda().eq(BizHenhouse::getId, henhouseId).select(BizHenhouse::getName);
        }
        if(ObjectUtil.isNotEmpty(columnId)){
            columnQueryWrapper.lambda().eq(BizColumn::getId, columnId).select(BizColumn::getName);
        }
        // 获取目标邮箱
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        String email = saBaseLoginUser.getEmail();

        String henhouseName = bizHenhouseMapper.selectOne(henhouseQueryWrapper).getName();
        String columnName = bizColumnMapper.selectOne(columnQueryWrapper).getName();
        String subject = "鸡悦乐-预警通知";
        String content = "鸡场的" + henhouseName + "的" + columnName + "出现异常，请及时处理！";

        log.info("向{}发送邮件，主题为：{}，内容为：{}",email,subject,content);
        SendEmailUtil.sendEmail(email,subject,content);
        return CommonResult.ok();
    }
}
